﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;

namespace Engine.Sgml.Test {
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class XPathFixture {
        public XPathFixture() {
            //
            // TODO: Add constructor logic here
            //
            }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
                }
            set {
                testContextInstance = value;
                }
            }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize() {
            DirectoryInfo fileDirectory = Directory.GetParent(TestContext.TestDir).Parent;

            DirectoryInfo schemaDirectory = new DirectoryInfo(Path.Combine(fileDirectory.FullName, @"Engine.Sgml.Test\Scheme Samples"));
            DirectoryInfo saveDirectory = new DirectoryInfo(Path.Combine(fileDirectory.FullName, @"Engine.Sgml.Test\Saved Docs"));
            fileDirectory = new DirectoryInfo(Path.Combine(fileDirectory.FullName, @"Engine.Sgml.Test\Document Samples"));

            Assert.IsTrue(schemaDirectory.Exists);
            Assert.IsTrue(fileDirectory.Exists);
            Assert.IsTrue(saveDirectory.Exists);

            fileDir = fileDirectory.FullName;
            }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        string fileDir;

        [TestMethod]
        public void SelectByElementPosition() {
            SgmlDocument doc = new SgmlDocument();
            
            doc.Settings.CaseSensitiveTags = false;
            doc.Load(new Uri(Path.Combine(fileDir, "XPath 001.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            Assert.IsNotNull(doc.SelectElement(".//BODY/DIV[1]"));
            Assert.IsNotNull(doc.SelectElement(".//BODY/div[1]"));
            Assert.IsNotNull(doc.SelectElement(".//BODY/div[2]"));
            }


        [TestMethod]
        public void GetXPathOfElement() {
            SgmlDocument doc = new SgmlDocument();
            doc.Load(new Uri(Path.Combine(fileDir, "XPath 002.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            SElement expectedElement = doc.SelectElement(".//input[@id]");
            string xpath = expectedElement.XPath();
            SElement selectedElement = doc.SelectElement(xpath);
            Assert.IsNotNull(selectedElement);
            Assert.IsTrue(selectedElement == expectedElement);

            SAttribute selectedAttribute = expectedElement.Attribute("id");
            xpath = selectedAttribute.XPath();
            SAttribute attribute = doc.Root.SelectAttribute(xpath);
            Assert.IsNotNull(attribute);
            Assert.IsTrue(attribute == selectedAttribute);

            expectedElement = doc.SelectElement(".//div[@class = 'txtsm']/text()");
            xpath = expectedElement.XPath();
            selectedElement = doc.SelectElement(xpath);
            Assert.IsNotNull(selectedElement);
            Assert.IsTrue(selectedElement == expectedElement);
            }

        [TestMethod]
        public void SelectElement() {
            SgmlDocument doc = new SgmlDocument();
            doc.Load(new Uri(Path.Combine(fileDir, "XPath 002.xml")));

            SElement td = doc.Root.FirstNode().LastNode().FirstNode().FirstNode().FirstNode().FirstNode().FirstNode().FirstNode();

            SElement selectedTd = doc.SelectElement(".//td[@class = 'tir pad5810']");
            Assert.IsNotNull(selectedTd);
            Assert.IsTrue(td == selectedTd);
            }

        [TestMethod]
        public void SelectElements() {
            SgmlDocument doc = new SgmlDocument();
            doc.Load(new Uri(Path.Combine(fileDir, "XPath 002.xml")));

            IEnumerable<SElement> rows = doc.SelectElements(".//FORM/div/table/TBODY/tr");
            Assert.IsTrue(rows.Count() > 0);
            SElement tbody = doc.Root.FirstNode().LastNode().FirstNode().FirstNode().FirstNode().FirstNode();

            int elementIndex = 0;
            foreach (SElement item in rows) {
                Assert.IsTrue(tbody.Nodes().ElementAt(elementIndex) == item);
                elementIndex++;
                }
            }

        [TestMethod]
        public void SelectAttribute() {
            SgmlDocument doc = new SgmlDocument();
            doc.Load(new Uri(Path.Combine(fileDir, "XPath 002.xml")));

            SAttribute attrClass = doc.Root.FirstNode().LastNode().FirstNode().FirstNode().FirstNode().FirstNode().FirstNode().FirstNode().LastAttribute();

            SAttribute selectedAttribute = doc.SelectAttribute(".//td/@class[last()]");
            Assert.IsNotNull(selectedAttribute);
            Assert.IsTrue(attrClass == selectedAttribute);
            }

        [TestMethod]
        public void SelectAttributes() {
            SgmlDocument doc = new SgmlDocument();
            doc.Load(new Uri(Path.Combine(fileDir, "XPath 002.xml")));

            string xml = doc.ToXml();

            IEnumerable<SAttribute> attributes = doc.SelectAttributes(".//input[@id = 'ZIP_BUTTON_2']/@*");
            Assert.IsTrue(attributes.Count() > 1);


            SElement input = doc.Root.FirstNode().LastNode().FirstNode().FirstNode().FirstNode().FirstNode().FirstNode().Nodes().ElementAt(3);
            input = input.FirstNode().Nodes().ElementAt(4).Nodes().ElementAt(1).FirstNode().FirstNode().FirstNode();
            input = input.Nodes().ElementAt(1).FirstNode();

            int elementIndex = 0;
            foreach (SAttribute item in attributes) {
                Assert.IsTrue(input.Attributes().ElementAt(elementIndex) == item);
                elementIndex++;
                }
            }
        }
    }
